home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / portsrv.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  3KB  |  140 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. /* This is a server for jove sub processes.  By the time we get here, our
  9.    standard output goes to jove's process input. */
  10.  
  11. #include "jove.h"
  12.  
  13. #ifdef    PIPEPROCS    /* the whole file! */
  14.  
  15. #include <signal.h>
  16. #include <sys/ioctl.h>
  17. #include "wait.h"
  18.  
  19. private struct header {
  20.     int    pid;
  21.     int    nbytes;
  22.     char    buf[512];
  23. } header;
  24.  
  25. private int    tty_fd;
  26.  
  27. #define HEADSIZE    ((sizeof header.pid) + sizeof (header.nbytes))
  28.  
  29. private void
  30. proc_write(ptr, n)
  31. UnivConstPtr    ptr;
  32. size_t    n;
  33. {
  34.     (void) write(1, ptr, n);
  35. }
  36.  
  37. private void
  38. read_pipe(fd)
  39. int    fd;
  40. {
  41.     register size_t    n;
  42.  
  43.     while ((header.nbytes = read(fd, (UnivPtr) header.buf, sizeof header.buf)) > 0) {
  44.         n = HEADSIZE + header.nbytes;
  45.         proc_write((UnivConstPtr) &header, n);
  46.     }
  47. }
  48.  
  49. private void
  50. proc_error(str)
  51. char    *str;
  52. {
  53.     header.pid = getpid();
  54.     header.nbytes = strlen(str);
  55.     strcpy(header.buf, str);
  56.     proc_write((UnivConstPtr) &header, header.nbytes + HEADSIZE);
  57.     write(tty_fd, str, strlen(str));
  58.     exit(-2);
  59. }
  60.  
  61. /* ARGSUSED */
  62. int
  63. main(argc, argv)
  64. int    argc;
  65. char    *argv[];
  66. {
  67.     int    p[2];
  68.     int    pid;
  69.  
  70.     if (pipe(p) == -1)
  71.         proc_error("Cannot pipe jove portsrv.\n");
  72.  
  73.     switch (pid = fork()) {
  74.     case -1:
  75.         proc_error("portsrv: cannot fork.\n");
  76.         /*NOTREACHED*/
  77.  
  78.     case 0:
  79.         /* We'll intercept childs output in p[0] */
  80.         (void) dup2(p[1], 1);
  81.         (void) dup2(p[1], 2);
  82.         (void) close(p[0]);
  83.         (void) close(p[1]);
  84.  
  85.         (void) setpgrp(getpid(), getpid());
  86.         execv(argv[1], (const char **) &argv[2]);
  87.         _exit(-4);
  88.         /*NOTREACHED*/
  89.  
  90.     default:
  91.         (void) close(0);
  92.         tty_fd = open("/dev/tty", 1);
  93.  
  94.         (void) signal(SIGINT, SIG_IGN);
  95.         (void) signal(SIGQUIT, SIG_IGN);
  96.         (void) close(p[1]);
  97.  
  98.         /* tell jove the pid of the real child as opposed to us */
  99.         header.pid = getpid();
  100.         header.nbytes = sizeof (int);
  101.         *(int *) header.buf = pid;
  102.         (void) write(1, (char *) &header, sizeof pid + HEADSIZE);
  103.  
  104.         /* read proc's output and send it to jove */
  105.         read_pipe(p[0]);
  106.  
  107.         /* received EOF - wait for child to die and then exit
  108.            ourself in the same way so that JOVE knows how the
  109.            child died.  This is sort of a kludge, but the alternative
  110.            is to write the childs status to JOVE, which seems sorta
  111.            yucky, too.
  112.  
  113.            Actually, 4 or 5 years later I like that idea much better,
  114.            so remind me to implement it that way when I get a chance.
  115.  
  116.            7-23-89  Gee thanks, whoever implemented this for me! */
  117.  
  118.         (void) close(p[0]);
  119.         header.pid = getpid();
  120.         header.nbytes = EOF;    /* tell jove we are finished */
  121.         /* try to exit like our child did ... */
  122.         {
  123.             union wait    status;
  124.  
  125.             do ; while (wait(&status) != pid);
  126.             *(int *) header.buf = status.w_status;
  127.         }
  128.         (void) write(1, (UnivConstPtr) &header, HEADSIZE + sizeof (int));
  129.     }
  130.     return 0;
  131. }
  132.  
  133. #else    /* !PIPEPROCS */
  134. int
  135. main()
  136. {
  137.     return 0;
  138. }
  139. #endif    /* !PIPEPROCS */
  140.